﻿using System;
using System.Data.Entity;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using System.Web.SessionState;
using SnippetBox.Core.Common.Mvc.Attributes;
using SnippetBox.Core.Common.Mvc.Routes;
using SnippetBox.Core.Data.Context;
using SnippetBox.Core.Data.Models;
using SnippetBox.Core.Data.Service;
using SnippetBox.Core.Infrastructure;
using SnippetBox.Core.Infrastructure.Security;

namespace SnippetBox.Web {

    public class MvcApplication : HttpApplication {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new SettingsAuthorizeAttribute());
            filters.Add(new ExportModelStateToTempData());
            filters.Add(new RequestTimingFilter());
        }

        public static void RegisterRoutes(RouteCollection routes) {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRouteLowercase(
                "Snippet-Details",
                "snippet/{categoryId}/{categorySlug}/{snippetId}/{snippetSlug}",
                new { controller = "Snippet", action = "Details", snippetId = "" },
                new { snippetId = "\\d+", categoryId = "\\d+" }
            );

            routes.MapRouteLowercase(
                "Category-Details",
                "snippet/{categoryId}/{categorySlug}",
                new { controller = "Category", action = "Details", categoryId = "" },
                new { categoryId = "\\d+" }
            );

            routes.MapRoute(
                "User-Details",
                "users/{username}",
                new { controller = "User", action = "Profile", username = "" }
            );

            routes.MapRoute(
                "User-Edit",
                "users/{username}/edit",
                new { controller = "User", action = "Edit", username = "" }
            );

            routes.MapRouteLowercase(
                "Default",
                "{controller}/{action}/{id}",
                new { controller = "Snippet", action = "Index", id = UrlParameter.Optional }
            );

        }

        protected void Application_Start() {
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new RazorViewEngine());

            SettingsWatcher.Init();
            Database.SetInitializer(new DatabaseMigration());

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

        protected void Application_AcquireRequestState(Object sender, EventArgs e) {
            if (!(Context.Handler is IRequiresSessionState)) return;
            if (Context.User == null || !Context.User.Identity.IsAuthenticated || Context.Session == null) return;

            try {
                User user = null;
                if (Context.Session["User"] != null) {
                    user = Context.Session["User"] as User;
                }
                else {

                    UserService userService = new UserService();
                    user = userService.GetByUsername(Context.User.Identity.Name);

                    if (user == null) {
                        FormsAuthentication.SignOut();
                        return;
                    }
                    Context.Session.Add("User", user);

                }

                Thread.CurrentPrincipal = Context.User = user;
            }
            catch { }

        }

    }
}